<script setup lang="ts">
import { ref, onBeforeMount } from 'vue'
import { ElMessage as message } from 'element-plus'
import tableColSetting from '@/components/tableColsSetting/tableColsSetting.vue'
import useRouteList, { actionKeys } from './routeList'
import { listToTree, setTableHeight,sortTreeArr} from '@/common/utils'
import { layoutRouteName } from '@/router/config'
import Add from './add.vue'
import Update from './update.vue'
import { h } from 'vue'
import { primaryColorFade } from '@/theme/config'
import { useResizeLR } from '@/hooks/useResizeLR'
import { useTableMixin } from '@/hooks/useTableMixin'

const columns = ref<tableColConfig[]>([
	{
		// checked:false,
		label: '路由名',
		prop: 'name',
		columnKey: 'name',
		width: 120,
		align: 'center',
	},
	{
		label: '组件路径',
		prop: 'component',
		columnKey: 'component',
		width: 150,
		// align:'center',
		showOverflowTooltip: true,
	},
	{
		label: '父级路由标题',
		prop: 'pTitle',
		columnKey: 'pTitle',
		width: 100,
		align: 'center',
	},
	{
		label: 'meta',
		prop: 'meta',
		columnKey: 'meta',
		align: 'center',
		childrenCols: [
			{
				label: '页面标题',
				prop: 'title',
				columnKey: 'title',
				width: 150,
				align: 'center',
			},
			{
				label: '菜单图标',
				prop: 'icon',
				columnKey: 'icon',
				width: 150,
				align: 'center',
			},
			{
				label: '一级菜单的排序序号',
				prop: 'rank',
				columnKey: 'rank',
				width: 150,
				align: 'center',
			},
			{
				label: '是否需要权限访问',
				prop: 'noNeedAuth',
				columnKey: 'noNeedAuth',
				width: 150,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.noNeedAuth ? h('span', { style: { color: 'rgb(245, 108, 108)' } }, '否') : h('span', { style: { color: 'rgb(29, 165, 122)' } }, '是')
				},
			},
			{
				label: '是否缓存',
				prop: 'noKeepAlive',
				columnKey: 'noKeepAlive',
				width: 100,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.noKeepAlive ? '否' : '是'
				},
			},
			{
				label: '是否存在菜单中',
				prop: 'onInMenu',
				columnKey: 'noInMenu',
				width: 120,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.noInMenu ? '否' : '是'
				},
			},
			{
				label: '是否隐藏菜单',
				prop: 'hiddenMenu',
				columnKey: 'hiddenMenu',
				width: 100,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.hiddenMenu ? '是' : '否'
				},
			},
			{
				label: '是否隐藏布局',
				prop: 'hiddenLayout',
				columnKey: 'hiddenLayout',
				width: 100,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.hiddenLayout ? '是' : '否'
				},
			},
			{
				label: '是否固定tab页',
				prop: 'affix',
				columnKey: 'affix',
				width: 120,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.affix ? '是' : '否'
				},
			},
			{
				label: '是否跳往外部链接',
				prop: 'link',
				columnKey: 'link',
				width: 120,
				align: 'center',
				contentRender: (scope: any) => {
					return scope.row.link ? '是' : '否'
				},
			},
		],
	},
	{
		disabled: true,
		label: '操作',
		prop: 'operation',
		columnKey: 'operation',
		align: 'center',
		fixed: 'right',
		resizable: false,
		width: 128,
	},
])

const treeData = ref<routeTreeNode[]>([])
const expandedKeys = ref<string[]>([layoutRouteName])
const selectedKey = ref('')
const hasChildKeys = ref<Set<string>>(new Set([]))
const treeHeight = ref<number>()
const selectedNode = ref({} as routeTreeNode)
const addRef = ref<InstanceType<typeof Add>>()
const updateRef = ref<InstanceType<typeof Update>>()
const addModalIsFull = ref(false)
const updateModalIsFull = ref(false)

const searchOptions = ref<searchOptionType[]>([
	{ type: 'input', id: 'name', props: { label: '路由名' } },
	{ type: 'input', id: 'component', props: { label: '组件路径' } },
	{ type: 'input', id: 'pTitle', props: { label: '父路由标题' } },
	{ type: 'input', id: 'title', props: { label: '路由标题' } },
	{
		type: 'select',
		id: 'noNeedAuth',
		props: { label: '是否需要权限访问' },
		innerComponentProps: {
			filterable: true,
			selectOptions: [
				{ label: '是', value: 0, disabled: false },
				{ label: '否', value: 1, disabled: false },
			],
		},
	},
	{
		type: 'select',
		id: 'onInMenu',
		props: { label: '是否存在在菜单' },
		innerComponentProps: {
			filterable: true,
			selectOptions: [
				{ label: '是', value: 0, disabled: false },
				{ label: '否', value: 1, disabled: false },
			],
		},
	},
	{
		type: 'select',
		id: 'noKeepAlive',
		props: { label: '是否缓存' },
		innerComponentProps: {
			filterable: true,
			selectOptions: [
				{ label: '是', value: 0, disabled: false },
				{ label: '否', value: 1, disabled: false },
			],
		},
	},
])

const routeList = useRouteList()

useResizeLR({
	containerSelector: '.routeManage .container',
	leftBoxSelector: '.routeManage .container .left',
	moveBarSelector: '.routeManage .container .bar',
	rightBoxSelector: '.routeManage .container .right',
	//  lMinW:180,
	rMinW: 800,
	innerMarginW: 10,
})
const {
	current, // 当前页码
	size, // 页尺寸
	total, // 总条数
	filterOptions, // 查询条件
	getData,        // 获取页数据的方法
	tableHeight, // 表格高度
	addDialogVisible, //新增模态框显示隐藏状态
	updateDialogVisible, //更新模态框显示隐藏状态
	tableList, // 表格数据
	editRow, // 当前编辑数据
	handleSearchPanelcollapsed, //search-panel组件的 @collapsed 的处理函数
	handleSearch, // 搜索处理函数
	handleReset, // 重置表格数据处理函数
	handlePaginationChange, // 处理分页器变化处理函数
	handleColumnsChange, // 表头变化组件的处理函数
	handleAdd, // 点击新增按钮回调
	handleUpdate, // 点击更新按钮回调
	handleDelete, // 删除处理函数
	handleAddCommit, // 新增提交处理函数
	handleUpdateCommit, // 更新提交处理函数
} = useTableMixin<routeTreeNode>({
	columns,
	listApiFunc: routeList.getPageList,
	deleteApiFunc: routeList.deleteItem,
	actionList: [actionKeys.update, actionKeys.delete],
	addRef,
	updateRef,
	searchPanelcollapsed_after: (h) => {
		setTableHeight({ tableHeightRef: treeHeight, otherSectionHeight: h + 52, isTable: false })
	},
	add_before: () => {
		if (!selectedKey.value) {
			message.warning('请先在左侧树选择父节点')
			return
		}
		if (selectedNode.value.component) {
			message.warning('选中的是叶子节点，不可添加子路由')
			return
		}
		if (selectedNode.value.link) {
			message.warning('选中的是外部链接，不可添加子路由')
			return
		}
		return true
	},
	update_before: () => {
		return true
	},
	delete_before: () => {
		return true
	},
	add_after: () => {
		getTreeData()
	},
	delete_after: () => {
		if(editRow.value.name==selectedNode.value.name){
			selectedNode.value = {} as routeTreeNode
	    selectedKey.value = ''
		}
		getTreeData()
	},
	query_after: () => {},
	update_after: () => {
		getTreeData()
	},
	search_after: () => {},
	reset_after: () => {
		selectedKey.value = ''
	},
})
onBeforeMount(() => {
	getTreeData()
})

async function getTreeData(list = routeList.list) {
	const res = await routeList.getList()
	if (res.code) {
		const tree = listToTree(
			list,
			'id',
			'pId',
			false,
			(i) => {
				if (i.component) i.class = 'greenText'
			},
			(j) => {
				hasChildKeys.value.add(j.name)
			}
		) as routeTreeNode
		// console.log(tree,[...list])
		treeData.value=sortTreeArr([tree],'rank')
		// console.log(tree)
	}
}
function customNodeClass(data: routeItemConfig, node: Node) {
	if (data.component || data.link) {
		return 'leafTextColor'
	}
	return null
}
function handleSelectTreeNode(node: routeTreeNode) {
	// console.log(node)
  filterOptions.value={name:node.name}
	getData()
	selectedNode.value = node
	selectedKey.value = node.name
	//console.log({...selectedNode.value})
}

function nodeContentRender(h: any, e: any) {
	// console.log(h,e)
	//console.log(e)
	if (selectedKey.value == e.data.name) return h('span', { style: { backgroundColor: primaryColorFade(0.5) } }, e.data.title)
	else return e.data.title
}
</script>

<template>
	<div class="routeManage">
		<search-panel @collapsed="handleSearchPanelcollapsed" @search="handleSearch" @reset="handleReset" :options="searchOptions" />
		<div class="container" style="display: flex">
			<div class="left" :style="{ height: treeHeight + 'px' }">
				<el-scrollbar>
					<el-tree
						:render-content="nodeContentRender"
						:expand-on-click-node="false"
						:props="{ children: 'children', label: 'title', class: customNodeClass }"
						node-key="name"
						:data="treeData"
						:default-expanded-keys="expandedKeys"
						@node-click="handleSelectTreeNode"
					/>
				</el-scrollbar>
			</div>
			<div class="bar" :style="{ height: treeHeight + 'px' }"></div>
			<div class="right">
				<div class="tableTool">
					<el-button type="primary" style="margin-right: 5px" @click="handleAdd" v-if="$hasAuth([actionKeys.add])">新增子路由</el-button>
					<tableColSetting :list="columns"  @confirm="handleColumnsChange" />
				</div>
				<!-- 加上border属性，所有列将可以调整宽度 -->
				<my-table
				  border
					:data="tableList"
					:columns="columns"
					size="small"
					style="width: 100%"
					class="myTable"
					rowKey="name"
					:maxHeight="tableHeight"
					:pagination="{
						pageSizes: [3,5,10, 20, 30, 40, 50],    
						small: true,
						background: true,
						layout: 'total, sizes, prev, pager, next, jumper',
						controlled:true,
						current,
						size,
						total,
						onCurrentChange:(page:number)=>{handlePaginationChange({page})},
						onSizeChange:(size:number)=>{handlePaginationChange({size})},
					}"
				>
					<template #operation="{ row }">
						<el-button type="primary" size="small" @click="handleUpdate(row)" v-if="$hasAuth([actionKeys.update])" :disabled="row.name == layoutRouteName">修改</el-button>
						<el-popconfirm title="确定要删除吗?" confirm-button-text="确定" cancel-button-text="取消" @confirm="handleDelete(row)" v-if="$hasAuth([actionKeys.delete])">
							<template #reference><el-button type="danger" size="small" :disabled="[...hasChildKeys].includes(row.name)">删除</el-button></template>
						</el-popconfirm>
					</template>
				</my-table>
			</div>
		</div>

		<el-dialog v-model="addDialogVisible" title="新增子路由" width="80%" :modal="false" draggable :close-on-click-modal="false" align-center :fullscreen="addModalIsFull">
			<el-scrollbar :maxHeight="addModalIsFull ? 0 : $getDialogBodyMaxHeight()">
				<!--  套个div防止无论何时都出现横向滚动 -->
				<div style="padding: 0 10px">
					<Add :parentNode="(selectedNode as any)" ref="addRef" />
				</div>
			</el-scrollbar>
			<template #footer>
				<div class="dialog-footer" style="display: flex; justify-content: flex-end">
					<screenFullToggleIcon @toggle="(v:boolean)=>{addModalIsFull=v}" />
					<el-button @click="addDialogVisible = false">取消</el-button>
					<el-button type="primary" @click="handleAddCommit">确定</el-button>
				</div>
			</template>
		</el-dialog>

		<el-dialog v-model="updateDialogVisible" title="更新子路由" width="80%" :modal="false" draggable :close-on-click-modal="false" align-center :fullscreen="updateModalIsFull">
			<el-scrollbar :maxHeight="updateModalIsFull ? 0 : $getDialogBodyMaxHeight()">
				<div style="padding: 0 10px">
					<Update :editNode="(editRow as any)" ref="updateRef" />
				</div>
			</el-scrollbar>
			<template #footer>
				<div class="dialog-footer" style="display: flex; justify-content: flex-end">
					<screenFullToggleIcon @toggle="(v:boolean)=>{updateModalIsFull=v}" />
					<el-button @click="addDialogVisible = false">取消</el-button>
					<el-button type="primary" @click="handleUpdateCommit">确定</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<style scoped lang="scss">
.routeManage {
	.container {
		.left {
			overflow: hidden auto;
			margin-top: 52px;
			background-color: white;
			width: 180px;
			flex-shrink: 0;
		}
		.bar {
			width: 5px;
			//background-color: gainsboro;
			margin: 52px 0 0 10px;
			background-clip: content-box;
			padding: 0 2px;
			flex-shrink: 0;
		}
		.bar:hover {
			background-color: gainsboro;
		}
		.right {
			padding-left: 20px;
			width: calc(100% - 180px - 15px);
		}
	}

	.tableTool {
		padding: 10px 0;
		display: flex;
		justify-content: flex-end;
		align-items: center;
	}
	:deep(.el-table thead .el-table__cell) {
		text-align: center;
		// background-color: rgb(232, 246, 241) !important;
	}
}
</style>
